/**
    ATClab - scriptable Air Traffic Control simulations.
    Copyright (C) 2010 openatclab@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/

#include "conflictdeclaration.h"


#include <limits>
#include <math.h>

using namespace atc;


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// atc::ConflictDeclaration
//
//--------------------------------------------------------------------------------------------------
// construction
//
ConflictDeclaration::ConflictDeclaration(const std::string& a_ac0, 
										 const std::string& a_ac1, 
										 const double		a_sep,
										 ConflictType		a_conflictType,
										 const long			a_finalTime) 
		:m_ac0(a_ac0 < a_ac1 ? a_ac0 : a_ac1)
		,m_ac1(a_ac0 < a_ac1 ? a_ac1 : a_ac0)
		,m_sep(a_sep)
		,m_conflictType(a_conflictType)
		,m_finalTime(a_finalTime)
		,m_action(NO_ACTION)
{
}

ConflictDeclaration::ConflictDeclaration(const ConflictDeclaration& a_lhs)
		: m_ac0(a_lhs.m_ac0)
		, m_ac1(a_lhs.m_ac1)
		, m_sep(a_lhs.m_sep)
		, m_conflictType(a_lhs.m_conflictType)
		, m_finalTime(a_lhs.m_finalTime)
		, m_action(a_lhs.m_action)
{
}

ConflictDeclaration::~ConflictDeclaration() 
{
}


//--------------------------------------------------------------------------------------------------
// [public]
//
ConflictAircraftPair 
ConflictDeclaration::conflict_pair() const 
{
	return std::make_pair(m_ac0, m_ac1);
}

bool
ConflictDeclaration::ConflictDeclaredOnTime(long a_currentTime) const
{
	return a_currentTime < (m_finalTime - CONFLICT_DECLARATION_THRESHOLD);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// atc::ConflictDeclarationBuilder
//
//--------------------------------------------------------------------------------------------------
//
//
ConflictDeclarationBuilder* 
ConflictDeclarationBuilder::set_separation(const double a_separation) 
{ 
	m_separation = a_separation; 

	return this;
}

ConflictDeclarationBuilder* 
ConflictDeclarationBuilder::add_aircraft(const std::string& a_callsign) 
{ 
	m_callsigns.insert(a_callsign); 

	return this;
}

ConflictDeclarationBuilder*
ConflictDeclarationBuilder::SetConflictType(ConflictDeclaration::ConflictType a_conflictType)
{
	m_conflictType = a_conflictType;

	return this;
}

ConflictDeclarationBuilder*
ConflictDeclarationBuilder::SetFinalTime(long a_finalTime)
{
	m_finalTime = a_finalTime;

	return this;
}
//--------------------------------------------------------------------------------------------------
//
//
ConflictDeclarationMap ConflictDeclarationBuilder::build() 
{
	ConflictDeclarationMap cdmap;
	
	std::set<std::string>::const_iterator callIt = m_callsigns.begin();
	for ( ; callIt != m_callsigns.end(); ++callIt ) 
	{
		std::set<std::string>::const_iterator it = callIt;
		for (++it; it != m_callsigns.end(); ++it) 
		{
			ConflictDeclaration cd = ConflictDeclaration(*callIt, *it, m_separation, m_conflictType, m_finalTime);
			cdmap.insert(std::make_pair( cd.conflict_pair(), cd));
		}
	}
	
	return cdmap;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
